package com.unrarme.utils
{
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.html.HTMLLoader;
	import flash.net.URLRequest;
	
	public class Aquery extends EventDispatcher
	{
		private var html:HTMLLoader;
		private var document:Object;
		
		public function Aquery(data:*)
		{
			html = new HTMLLoader();
			html.addEventListener(Event.COMPLETE, HTMLLoaderCompleteHandler);
			if (typeof(data) == 'string') {
				html.loadString(data);
			} else {
				html.load(data);
			}
			
		}
		
		private function HTMLLoaderCompleteHandler(e:Event):void {
			this.document = this.html.window.document;
			this.dispatchEvent(new Event(Event.COMPLETE));
		}
		
		public function select(tagString:String):Array {
			var elements:* = this.document;
			var tags:* = parseTags(tagString);
			
			for each (var tag:Object in tags) {
				elements = removeDuplicates(this.getElements(elements, tag));
			}
			
			return elements;
		}
		
		private function getElements(elements:*, tag:Object):Array {
			var result:Array = new Array();
			
			for each (var el:* in elements) {
				if ((typeof(el) == typeof(new Object()))&&(el != null)) {
					if (el.hasOwnProperty("getElementsByTagName")) {
						var els:* = el.getElementsByTagName(tag["tagName"]);
						for each (var element:* in els) {
							if (typeof(element) == typeof(new Object())) {
								if (((element.tagName as String).toLowerCase() == (tag["tagName"] as String).toLowerCase())||(tag["tagName"] == '*')) {
									if(tag.hasOwnProperty("attributeName")) {
										if (element.getAttribute(tag["attributeName"]) == tag["attributeValue"]) {
											if (tag.hasOwnProperty("className")) {
												if(tag["className"] == element.className) {
													result.push(element);
												}
											} else {
												result.push(element);
											}
										}
									} else {
										if (tag.hasOwnProperty("className")) {
											if(tag["className"] == element.className) {
												result.push(element);
											}
										} else {
											result.push(element);
										}
									}
								}  // lowercase
							}
						} // for each
					} //if
				} //if typeof
			} // foreach 
			return result;
		}
		
		private function parseTags(selectorString:String):Array {
			var result:Array = new Array();
			var re:RegExp = new RegExp(/\[(.*?)=(.*?)\]/);
			
			var selectors:Array = selectorString.split(" ");
			for each (var tag:String in selectors) {
				var t:Object = {};
				if(re.test(tag)) {
					var r:Object = re.exec(tag);
					t["attributeName"] = r[1];
					t["attributeValue"] = r[2];
					tag = tag.replace(/\[(.*?)\]/, "").replace("\[", "").replace("\]", "");
				}
				
				var s:Array = tag.split(".");
				if (s.length > 1) {
					if (s[0] == '') {
						t["tagName"] = "*";
						t["className"] = s[1];
					} else {
						t["tagName"] = s[0];
						t["className"] = s[1];
					}
				} else {
					t["tagName"] = tag;
				}
				result.push(t);
			}
			
			return result;
		}
		
		private function removeDuplicates(elements:Array):Array {
			var result:Array = new Array();
			for(var i:int = 0; i < elements.length; i++){
				if(!contains(result, elements[i])){
					result.push(elements[i]);
				}
			}
			return result;
		}
		
		private function contains(a, e) {
			for(var j:int = 0; j < a.length; j++) {
				if (a[j].innerHTML == e.innerHTML) {
					return true;
				}
			}
			return false;
		}
	}
}